package org.dslintegration.merge.wizard;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import org.dslintegration.mRules.MergeRules;
import org.dslintegration.merge.InstanceLoader;
import org.dslintegration.merge.core.MergeEngine;
import org.dslintegration.merge.core.exception.MergeException;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleConstants;
import org.eclipse.ui.console.IConsoleManager;
import org.eclipse.ui.console.IConsoleView;
import org.eclipse.ui.console.MessageConsole;
import org.eclipse.ui.console.MessageConsoleStream;

public class MergeWizard extends Wizard {
	private String CONSOLE_NAME = "Merge";
	private MergeWizardPage mergeWizardPage;
	private String pathToFile = null;

	public MergeWizard() {
		super();
	}

	@Override
	public void addPages() {
		mergeWizardPage = new MergeWizardPage(pathToFile);
		addPage(mergeWizardPage);
	}

	private MessageConsole findConsole(String name) {
		ConsolePlugin plugin = ConsolePlugin.getDefault();
		IConsoleManager conMan = plugin.getConsoleManager();
		IConsole[] existing = conMan.getConsoles();
		MessageConsole mconsole = null;
		for (int i = 0; i < existing.length; i++)
			if (name.equals(existing[i].getName())) {
				MessageConsole console = (MessageConsole) existing[i];

				mconsole = console;
				break;
			}

		if (mconsole == null) {
			// no console found, so create a new one
			mconsole = new MessageConsole(name, null);
			conMan.addConsoles(new IConsole[] { mconsole });

		}

		// display it
		IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();

		IConsoleView view = null;
		try {
			view = (IConsoleView) page.showView(IConsoleConstants.ID_CONSOLE_VIEW);
		} catch (PartInitException e) {
			e.printStackTrace();
		}
		if (view != null)
			view.display(mconsole);

		return mconsole;
	}

	@Override
	public boolean performFinish() {
		String pathName = mergeWizardPage.getOutputLocation().getText();
		final File file = new File(pathName);
		file.mkdirs();
		final File outFile = new File(file, "/" + mergeWizardPage.getOutputName().getText());

		final boolean km3export = mergeWizardPage.getKm3().getSelection();
		final boolean xmiexport = mergeWizardPage.getXmi().getSelection();
		final boolean emfexport = mergeWizardPage.getXmi().getSelection();

		PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
			// We want to run a thread here
			@Override
			public void run() {
				MergeRules rules;
				MessageConsole console = findConsole(CONSOLE_NAME);
				MessageConsoleStream out = console.newMessageStream();
				out.println("Starting Merge Process");

				try {
					rules = InstanceLoader.loadRules(new File(pathToFile));
					MergeEngine engine = null;
					try {
						// We should most definitely write progress to make it seem legitimate
						engine = new MergeEngine(rules, out);
					} catch (MergeException e) {
						out.println(e.getMessage());
						e.printStackTrace();
						return;
					}

					// Default is history export
					try {
						File history = new File(file + "/history.txt");
						history.createNewFile();
						FileOutputStream fos = new FileOutputStream(history);
						fos.write(engine.getHistory().getBytes());
						fos.flush();
						fos.close();
					} catch (IOException e) {
						out.write(e.getMessage());
					}

					if (km3export)
						engine.exportAsKM3(outFile);
					if (xmiexport)
						engine.exportAsXMI(outFile);
					if (emfexport)
						engine.exportAsEcore(outFile);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				out.println("Finished");

				// TODO: Refresh the file
			}
		});

		return true;
	}

	public void setPath(String path) {
		pathToFile = path;
	}

}
